package com.deuwise.system.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.deuwise.system.entity.SysLayerDict;
import io.swagger.annotations.*;
import io.swagger.annotations.ApiImplicitParams;
import com.deuwise.common.utils.R;
import com.deuwise.common.utils.Result;
import com.baomidou.mybatisplus.plugins.Page;
import com.deuwise.system.entity.SysMapViewsDict;
import com.deuwise.system.service.SysMapViewsDictService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

/**
 *@author deuwise
 *@date 2020-06-08 17:22:30
 */
@Api(tags = "视图配置字典模块", description = "")
@RequestMapping("system/sysMapViewsDict")
@RestController()
public class SysMapViewsDictController extends AbstractController{
    @Autowired
    private SysMapViewsDictService sysMapViewsDictService;

    @ApiOperation(value = "获取list", notes = "")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "field", value = "字段", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "typeName", value = "地图类型名称", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "version", value = "版本号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "currentPage", value = "开始页数", defaultValue = "1", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页多少条", defaultValue = "15", dataType = "int", paramType = "query")})
    public Result<Page<SysMapViewsDict>> list(String field, String typeName, String version){
        Wrapper<SysMapViewsDict> wrapper = new EntityWrapper<SysMapViewsDict>();
        if(StringUtils.isNotBlank(field)){
            wrapper.like("field", field);
        }
        if(StringUtils.isNotBlank(typeName)){
            wrapper.like("type_name", typeName);
        }
        if(StringUtils.isNotBlank(version)){
            wrapper.eq("version", version);
        }
        Page<SysMapViewsDict> listPage = sysMapViewsDictService.selectPage(getPage(SysMapViewsDict.class),wrapper);
        return Result.ok(listPage);
    }

    @ApiOperation(value = "已经更新视图类型列表")
    @GetMapping("/layerVersionList")
    public R viewTypeVersion(){
        List<String> list = sysMapViewsDictService.viewTypeVersionList();
        return R.ok(list);
    }

    @ApiOperation(value = "视图配置属性同步")
    @GetMapping("/syncViewsProperty")
    public R syncViewsProperty(String apiUrl){
        if (StringUtils.isBlank(apiUrl)) {
            System.out.println("API地址不能为空！");
            return R.error(200,"ArcGis API地址不正确");
        }
        return getViewsList(apiUrl);
    }

    /**
     * 获取图层列表
     * @param url
     * @return
     */
    public R getViewsList(String url){
        StringBuffer urlSB = new StringBuffer();
        urlSB.append(url);
        urlSB.append("/latest/api-reference/");
        // 视图内容，GroundView属性都是只读的，过滤不同步
        String[] resultArr = {"MapView", "SceneView"};

        List<String> success = new ArrayList<String>();
        List<String> fail = new ArrayList<String>();
        for (String view : resultArr) {
            /*图层属性获取更新*/
            R r = syncViewsProperty(url, view);
            if (0 == (int)r.get("code")) {
                success.add(view);
            }else {
                fail.add(view);
            }
        }
        Map<String,List<String>> resultMap = new HashMap<>(16);
        resultMap.put("更新成功视图", success);
        resultMap.put("更新失败视图", fail);
        return R.ok(resultMap);
    }

    /**
     * 根据图层版本号同步更新图层属性
     * @param url
     * @param viewName
     * @return
     */
    public R syncViewsProperty(String url,String viewName) {
        boolean flag = false;
        StringBuffer urlSb=new StringBuffer();
        if (StringUtils.isBlank(viewName)) {
            return R.error(200,"");
        }
        urlSb.append(url);
        urlSb.append("/latest/api-reference/esri-views-");
        urlSb.append(viewName);
        urlSb.append(".html");

        InputStream is=null;
        BufferedReader br=null;
        StringBuffer html=new StringBuffer();
        String  temp="";
        try {
            URL url2 = new URL(urlSb.toString());
            /*打开流，准备开始读取数据;*/
            is = url2.openStream();
            br= new BufferedReader(new InputStreamReader(is));
            while ((temp = br.readLine()) != null) {
                html.append(temp);
            }
            /*接下来是关闭流,防止资源的浪费;*/
            if(is!=null)
            {
                is.close();
                is=null;
            }
            List<SysMapViewsDict> addList = new ArrayList<>();
            String layerType = "";
            /*通过Jsoup解析页面,生成一个document对象;*/
            Document doc = Jsoup.parse(html.toString());

            /*API版本号获取*/
            String version = doc.getElementsByClass("secondary-nav-title tablet-hide").get(0).getElementsByTag("a").text();
            version = version.split(" ")[2];

            /*通过class的名字得到（前端选择器，不是类！）*/
            Elements elements = doc.getElementsByClass("table table-properties");
            Iterator<Element> iterator = elements.iterator();
            while(iterator.hasNext()){
                Element elemen = iterator.next();
                // 遍历属性列表行 tr
                Elements elementTr =  elemen.getElementsByTag("tr");
                // 去掉表头，所以下标从1开始
                for(int i = 1; i < elementTr.size(); i++){
                    Elements elementTd = elementTr.get(i).getElementsByTag("td");
                    if(0 < elementTd.size()){
                        // 遍历属性列表行 tr中的列 td,get(0) 表示第一列为 属性
                        Element element =  elementTd.get(0);
                        if(null != element){
                            // 属性字段获取
                            String field = element.getElementsByTag("a").text();
                            // 验证属性是否只读
                            boolean isflg = propertyVerification(doc, field);
                            if(!isflg) {
                                /*构造对象*/
                                SysMapViewsDict sysLayerDict = new SysMapViewsDict();
                                sysLayerDict.setTypeName(viewName);
                                sysLayerDict.setVersion(version);
                                sysLayerDict.setField(field);
                                addList.add(sysLayerDict);
                            }
                        }
                    }
                }
            }
            /*移除当前版本图层对应属性*/
            if(deleteSysMapViewsDictByV(version,viewName)) {
                /*执行入库操作*/
                if(0 < addList.size()){
                    flag = sysMapViewsDictService.insertBatch(addList);
                }
            }
            System.out.println(viewName + ":==========视图属性解析完成===========");
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return R.error(200,"ArcGis API地址不正确！");
        } catch (IOException e) {
            e.printStackTrace();
            return R.error(200,"图层属性同步异常，请稍后再试！");
        }

        return flag == true ? R.ok() : R.error();
    }

    /**
     * 移除指定版本号的视图属性
     * @param version 版本号
     * @param viewName 视图名称
     * @return
     */
    public boolean deleteSysMapViewsDictByV(String version, String viewName) {
        Wrapper<SysMapViewsDict> wrapper = new EntityWrapper<SysMapViewsDict>();
        if (StringUtils.isNotBlank(version)) {
            wrapper.eq("version", version);
        }
        if (StringUtils.isNotBlank(viewName)) {
            wrapper.eq("type_name", viewName);
        }
        return sysMapViewsDictService.delete(wrapper);
    }

    /**
     * 判断属性字段是否为只读
     * @param doc
     * @param propertyName 属性名称(字段)
     * @return
     */
    public boolean propertyVerification(Document doc, String propertyName){
        Element element = doc.getElementById(propertyName);
        Elements elements = element.getElementsByClass("type-signature");
        for(Element element1 : elements){
            // 签名类型
            String typeSignature = element1.text();
            if("readonly".equals(typeSignature)){
                return true;
            }
        }
        return false;
    }

}